//==================================================================
//  Copyright (C) 2006-2007  Davide Pasca
//
//  This library is free software; you can redistribute it and/or
//  modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  This library is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with this library; if not, write to the Free Software
//  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
//==================================================================
///
///
///
///
///
//==================================================================

//==================================================================
//#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <mmsystem.h>
#include <stdlib.h>
#include <malloc.h>
#include <memory.h>
#include <tchar.h>

#include <gl/glew.h>
#include <gl/wglew.h>
#include <math.h>
#include <stdio.h>
#include "psys.h"
#include "appbase3.h"

#include "../include/resource.h"


//==================================================================
extern void main( Window *main_winp );

//==================================================================
static std::vector<HWND>	_modeless_list;

//==================================================================
void appbase_add_modeless_dialog( void *hwnd )
{
	_modeless_list.push_back( (HWND)hwnd );
}

//==================================================================
void appbase_rem_modeless_dialog( const void *hwnd )
{
	for (int i=0; i < _modeless_list.size(); ++i)
	{
		if ( _modeless_list[i] == hwnd )
		{
			_modeless_list.erase( _modeless_list.begin() + i );
			return;
		}
	}

	PASSERT( 0 );
}
/*
//==================================================================
int appbase_mainloop()
{
MSG		msg;

	while (1)
	{
		main_anim();	// animate

		while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
		{
			bool	is_msg_for_modeless_dialog = false;
			for (int i=0; i < _modeless_list.size(); ++i)
			{
				if ( IsDialogMessage( _modeless_list[i], &msg ) )
				{
					is_msg_for_modeless_dialog = true;
					break;
				}
			}

			if NOT( is_msg_for_modeless_dialog )
			{
				if (!TranslateAccelerator(msg.hwnd, _hAccelTable, &msg)) 
				{
					TranslateMessage(&msg);
					DispatchMessage(&msg);
				}
			}

			if ( msg.message == WM_QUIT )
				goto outtahere;
		}

		if ( main_requestquit() )
			PostQuitMessage( 0 );
	}

outtahere:
	return msg.wParam;
}
*/

//==================================================================
static LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
	{
	case WM_INITDIALOG:
		return TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
		{
			EndDialog(hDlg, LOWORD(wParam));
			return TRUE;
		}
		break;
	}
	return FALSE;
}

//==================================================================
int appbase_filerequest_open( Window *winp, 
							  TCHAR *out_pathnamep, int sizeof_pathname,
							  TCHAR *out_filenamep, int sizeof_filename,
							  int *io_fileindexp,
							  const TCHAR *filterp )
{
	OPENFILENAME	ofn;

    *out_pathnamep = '\0';

	ofn.lStructSize			= sizeof(OPENFILENAME);
	ofn.hwndOwner			= (winp ? winp->_hwnd : 0);
	ofn.lpstrFilter			= filterp;
	ofn.lpstrCustomFilter	= NULL;
	ofn.nMaxCustFilter		= 0L;
	ofn.nFilterIndex		= (io_fileindexp ? *io_fileindexp : 0);
	ofn.lpstrFile			= out_pathnamep;
	ofn.nMaxFile			= sizeof_pathname;
	ofn.lpstrFileTitle		= out_filenamep;
	ofn.nMaxFileTitle		= sizeof_filename;
	ofn.lpstrTitle			= NULL;
	ofn.lpstrInitialDir		= NULL;
	ofn.Flags				= 0;
	ofn.nFileOffset			= 0;
	ofn.nFileExtension		= 0;
	ofn.lpstrDefExt			= 0;

    if ( GetOpenFileName(&ofn) == 0 )
        return 0;

	if ( io_fileindexp )
		*io_fileindexp = ofn.nFilterIndex;

	return 1;
}

//==================================================================
int appbase_filerequest_save( Window *winp, 
							  TCHAR *out_pathnamep, int sizeof_pathname,
							  TCHAR *out_filenamep, int sizeof_filename,
							  int *io_fileindexp,
							  const TCHAR *filterp, const TCHAR *defextp )
{
OPENFILENAME	ofn;

    *out_pathnamep = '\0';

	ofn.lStructSize			= sizeof(OPENFILENAME);
	ofn.hwndOwner			= (winp ? winp->_hwnd : 0);
	ofn.lpstrFilter			= filterp;
	ofn.lpstrCustomFilter	= NULL;
	ofn.nMaxCustFilter		= 0L;
	ofn.nFilterIndex		= (io_fileindexp ? *io_fileindexp : 0);
	ofn.lpstrFile			= out_pathnamep;
	ofn.nMaxFile			= sizeof_pathname;
	ofn.lpstrFileTitle		= out_filenamep;
	ofn.nMaxFileTitle		= sizeof_filename;
	ofn.lpstrTitle			= NULL;
	ofn.lpstrInitialDir		= NULL;
	ofn.Flags				= 0;
	ofn.nFileOffset			= 0;
	ofn.nFileExtension		= 0;
	ofn.lpstrDefExt			= defextp;

    if ( GetSaveFileName(&ofn) == 0 )
        return 0;

	if ( io_fileindexp )
		*io_fileindexp = ofn.nFilterIndex;

	return 1;
}

//==================================================================
bool Application::Idle()
{
	MSG	msg;

	while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
	{
		bool	is_msg_for_modeless_dialog = false;
		for (int i=0; i < _modeless_list.size(); ++i)
		{
			if ( IsDialogMessage( _modeless_list[i], &msg ) )
			{
				is_msg_for_modeless_dialog = true;
				break;
			}
		}

		if NOT( is_msg_for_modeless_dialog )
		{
			if (!TranslateAccelerator(msg.hwnd, _hAccelTable, &msg)) 
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}

		if ( msg.message == WM_QUIT )
			return true;
	}

	//if ( main_requestquit() )
	//	PostQuitMessage( 0 );

	return false;
}

//==================================================================
void Application::AddModelessDialog( HWND hwnd )
{
	_modeless_list.push_back( (HWND)hwnd );
}

//==================================================================
void Application::RemoveModelessDialog( HWND hwnd )
{
	for (int i=0; i < _modeless_list.size(); ++i)
	{
		if ( _modeless_list[i] == hwnd )
		{
			_modeless_list.erase( _modeless_list.begin() + i );
			return;
		}
	}

	PASSERT( 0 );
}